package com.abel.bigwater.data.kente

import com.abel.bigwater.data.mapper.DataMapper
import com.abel.bigwater.data.mapper.RtuMapper
import io.netty.channel.ChannelHandlerContext
import io.netty.channel.socket.DatagramPacket
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import org.slf4j.LoggerFactory

class KenteUdpHandler(dataMapper: DataMapper, rtuMapper: RtuMapper, firmId: String, firmCode: String) : KenteTcpHandler(dataMapper, rtuMapper, firmId, firmCode) {
    override fun channelRead(ctx: ChannelHandlerContext?, msg: Any?) {
        lgr.info("GOT UDP: ${msg}")
        if (msg is DatagramPacket) {
            try {
                val p = KentePacket.parse(msg.content())

                p?.forEach {
                    GlobalScope.async {
                        try {
                            storeData(it)
                        } catch (ex: Exception) {
                            lgr.error("UDP保存数据异常: ${ex.message}", ex)
                        }
                    }
                }

                lgr.info("UDP replying: OK")
                ctx!!.writeAndFlush(DatagramPacket(ctx.alloc().buffer().writeBytes("OK".toByteArray()), msg.sender()))
            } catch (ex: Exception) {
                lgr.error("UDP异常: ${ex.message}", ex)
            }
        }
    }

    /**
     * should overwrite exception-caught, because UDP context CANNOT be closed.
     */
    override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
        lgr.error("UDP端口异常: ${cause?.message}", cause)
    }

    companion object {

        private val lgr = LoggerFactory.getLogger(KenteUdpHandler::class.java)
    }
}